package com.v9.main.controller.common;

import com.v9.common.annotation.Name;
import com.v9.common.core.service.SelectDataProvider;
import com.v9.common.dto.ProviderTypeDto;
import com.v9.common.exception.BizException;
import com.v9.common.model.GenderTypeEnum;
import com.v9.common.utils.IGlossary;
import com.v9.common.utils.ValuePare;
import com.v9.flow.domain.model.SponsorTypeEnum;
import com.v9.system.domain.CodeTable;
import com.v9.system.domain.CodeTableType;
import com.v9.system.service.CodeTableService;
import com.v9.system.service.CodeTableTypeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lunshi
 */
@RestController
@Tag(name = "下拉列表数据提供器")
@RequestMapping(value = "/sys/select", method = RequestMethod.POST)
public class SelectDataProviderController implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Resource
    private CodeTableService codeTableService;

    @Resource
    private CodeTableTypeService codeTableTypeService;
    private static Map<String, Class> enumMap = new HashMap<>();

    static {
        enumMap.put("flowGroupType", SponsorTypeEnum.class);
        enumMap.put("genderType", GenderTypeEnum.class);
    }

    @RequestMapping("list/{selectType}")
    @Operation(summary = "下拉控件值列表")
    public List<ValuePare> build(@PathVariable String selectType) {
        if ("status".equals(selectType)) {
            List<ValuePare> result = new ArrayList<>();
            result.add(new ValuePare(true, "是"));
            result.add(new ValuePare(false, "否"));
            return result;
        }
        Class aClass = enumMap.get(selectType);
        if (aClass != null) {
            List<ValuePare> results = new ArrayList<>();
            Object[] enumConstants = aClass.getEnumConstants();
            for (Object o : enumConstants) {
                IGlossary item = (IGlossary) o;
                String name = ((Enum) item).name();
                ValuePare value = new ValuePare();
                value.setId(name);
                value.setLabel(item.getRemark());
                results.add(value);
            }
            return results;
        }

        String[] beanNamesForType = this.applicationContext.getBeanNamesForType(SelectDataProvider.class);
        for (String type : beanNamesForType) {
            SelectDataProvider bean = (SelectDataProvider) applicationContext.getBean(type);
            if (bean.buildTypeCode().equals(selectType)) {
                return bean.buildData();
            }
        }

        CodeTableType typeQuery = new CodeTableType();
        typeQuery.setCode(selectType);
        typeQuery = codeTableTypeService.findByOne(typeQuery);
        if (typeQuery == null) {
            throw new BizException("非法操作");
        }
        CodeTable entity = new CodeTable();
        entity.setCodeType(selectType);
        List<CodeTable> query = codeTableService.query(entity);
        List<ValuePare> results = new ArrayList<>();
        query.forEach(item -> {
            results.add(new ValuePare(item.getCode(), item.getName()));
        });
        return results;

    }

    @RequestMapping("types")
    @Operation(summary = "提供器类型")
    public List<ProviderTypeDto> types() {
        String[] beanNamesForType = this.applicationContext.getBeanNamesForType(SelectDataProvider.class);
        List<ProviderTypeDto> results = new ArrayList<>();
        for (String type : beanNamesForType) {
            SelectDataProvider bean = (SelectDataProvider) applicationContext.getBean(type);
            ProviderTypeDto e = new ProviderTypeDto();
            e.setName(bean.buildTypeName());
            e.setCode(bean.buildTypeCode());
            results.add(e);
        }

        enumMap.forEach((k, v) -> {
            ProviderTypeDto dto = new ProviderTypeDto();
            dto.setCode(k);
            Name annotation = (Name) v.getAnnotation(Name.class);
            if(annotation!=null) {
                dto.setName(annotation.value());
            }
            results.add(dto);
        });
        ProviderTypeDto e = new ProviderTypeDto();
        e.setCode("status");
        e.setName("状态");
        results.add(e);
        return results;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }


}
